
import moment from 'moment'
import _ from 'lodash'
import * as groupProxy from '../../proxys/group'
import * as userProxy from '../../proxys/user'
import { toPageInfo, filterRangePicker, filterFindString, validRule } from '../../utils'
import { CODE, ErrorInfo } from '../../error'
import { MASTER_GROUP_LEVEL } from '../../middlewares/auth'

const page_size = 25

export const getlist = async (auth, req, res, next) => {
  if (auth.group.flag.indexOf('9011') === -1 && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_LICENSE_FLAG_OPERATION)
  }
  let listProxy = await getListProxy(req)
  return next(listProxy)
}

export const create = async (auth, req, res, next) => {
  let { username, group, password, email, nickname } = req.body
  if (auth.group.flag.indexOf('9012') === -1 && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_LICENSE_FLAG_OPERATION)
  }
  let info = null
  if (_.isEmpty(_.trim(username))) {
    return res.api(null, CODE.ERROR_VALID_USERNAME_REQUIRED)
  }
  let ruleUsername = validRule('username', _.trim(username))
  if (!ruleUsername.valid) {
    return res.api(null, CODE.ERROR_VALID_USERNAME_FORMAT, [ruleUsername.message])
  }
  info = { ...info, username: _.trim(username) }
  if (_.isEmpty(_.trim(group))) {
    return res.api(null, CODE.ERROR_VALID_GROUP_REQUIRED)
  }
  let groupLevel = await groupProxy.getInfo({ _id: _.trim(group) }, 'level')
  if (!groupLevel) {
    return res.api(null, CODE.ERROR_VALID_GROUP_NOEXISTS)
  }
  if (auth.group.level <= groupLevel) {
    return res.api(null, CODE.ERROR_BYLOND_LEVEL_OPERATION)
  }
  info = { ...info, group: _.trim(group) }
  if (_.isEmpty(_.trim(password))) {
    return res.api(null, CODE.ERROR_VALID_PASSWORD_REQUIRED)
  }
  let rulePassword = validRule('password', _.trim('password'))
  if (!rulePassword.valid) {
    return res.api(null, CODE.ERROR_VALID_PASSWORD_FORMAT, [rulePassword.message])
  }
  info = { ...info, password: _.trim(password) }
  if (_.isEmpty(_.trim(email))) {
    return res.api(null, CODE.ERROR_VALID_EMAIL_REQUIRED)
  }
  let ruleEmail = validRule('email', _.trim(email))
  if (!ruleEmail.valid) {
    return res.api(null, CODE.ERROR_VALID_EMAIL_FORMAT)
  }
  info = { ...info, email: _.trim(email) }
  if (nickname) {
    let ruleNickname = validRule('nickname', _.trim(nickname))
    if (!ruleNickname.valid) {
      return res.api(null, CODE.ERROR_VALID_NICKNAME_FORMAT, [ruleNickname.message])
    }
    info = { ...info, nickname: _.trim(nickname) }
  }
  let listProxy = await getListProxy(req)
  return next({ info, ...listProxy })
}

export const findUser = (auth, req, res, next) => {
  let { type } = req.params
  let query = null
  if (_.has(req.query, 'v')) {
    query = { [type]: { $eq: _.trim(req.query['v']) } }
  }
  if (!query) return res.api(null)
  if (_.has(req.query, 'exc')) {
    query[type] = { ...query[type], $ne: _.trim(req.query['exc']) }
  }
  return next({ query, type })
}

export const edit = async (auth, req, res, next) => {
  let { _id } = req.params
  let { username, group, password, email, nickname } = req.body
  if (auth.group.flag.indexOf('9013') === -1 && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_LICENSE_FLAG_OPERATION)
  }
  let ruleUserId = validRule('objectId', _id)
  if (!ruleUserId.valid) {
    return res.api(null, CODE.ERROR_VALID_IDMARK_NOTEXIST)
  }
  let userInfo = await userProxy.getInfo({ _id })
  if (!userInfo) {
    return res.api(null, CODE.ERROR_VALID_IDMARK_NOTEXIST)
  }
  if (userInfo.group.level >= auth.group.level && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_BYLOND_LEVEL_OPERATION)
  }
  let info = null
  if (_.isEmpty(_.trim(username))) {
    return res.api(null, CODE.ERROR_VALID_USERNAME_REQUIRED)
  }
  let ruleUsername = validRule('username', _.trim(username))
  if (!ruleUsername.valid) {
    return res.api(null, CODE.ERROR_VALID_USERNAME_FORMAT, [ruleUsername.message])
  }
  info = { ...info, username: _.trim(username) }
  if (!(auth.group.level === MASTER_GROUP_LEVEL && _.isEmpty(_.trim(group)))) {
    if (_.isEmpty(_.trim(group))) {
      return res.api(null, CODE.ERROR_VALID_GROUP_REQUIRED)
    }
    let groupLevel = await groupProxy.getInfo({ _id: _.trim(group) }, 'level')
    if (!groupLevel) {
      return res.api(null, CODE.ERROR_VALID_GROUP_NOEXISTS)
    }
    if (auth.group.level <= groupLevel) {
      return res.api(null, CODE.ERROR_BYLOND_LEVEL_OPERATION)
    }
    info = { ...info, group: _.trim(group) }
  }
  if (!_.isEmpty(_.trim(password))) {
    let rulePassword = validRule('password', _.trim('password'))
    if (!rulePassword.valid) {
      return res.api(null, CODE.ERROR_VALID_PASSWORD_FORMAT, [rulePassword.message])
    }
    info = { ...info, password: _.trim(password) }
  }
  if (_.isEmpty(_.trim(email))) {
    return res.api(null, CODE.ERROR_VALID_EMAIL_REQUIRED)
  }
  let ruleEmail = validRule('email', _.trim(email))
  if (!ruleEmail.valid) {
    return res.api(null, CODE.ERROR_VALID_EMAIL_FORMAT)
  }
  info = { ...info, email: _.trim(email) }
  if (nickname) {
    let ruleNickname = validRule('nickname', _.trim(nickname))
    if (!ruleNickname.valid) {
      return res.api(null, CODE.ERROR_VALID_NICKNAME_FORMAT, [ruleNickname.message])
    }
  }
  info = { ...info, nickname: _.trim(nickname) }
  return next({ _id, info })
}

export const remove = async (auth, req, res, next) => {
  let { _id } = req.body
  if (auth.group.flag.indexOf('9014') === -1 && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_LICENSE_FLAG_OPERATION)
  }
  let group_id_in = await groupProxy.getObjectId({ level: { $lt: auth.group.level }})
  let remove = {
    _id: { $in: _.isArray(_id) ? _id : [_id] },
    group: { $in: group_id_in }
  }
  let listProxy = await getListProxy(req)
  return next({ remove, ...listProxy })
}

export const setStatus = async (auth, req, res, next) => {
  let { _id, freeze, lock } = req.body
  if (auth.group.flag.indexOf('9015') === -1 && auth.group.level !== MASTER_GROUP_LEVEL) {
    return res.api(null, CODE.ERROR_LICENSE_FLAG_OPERATION)
  }
  let group_id_in = await groupProxy.getObjectId({ level: { $lt: auth.group.level }})
  let update = {
    _id: { $in: _.isArray(_id) ? _id : [_id] },
    group: { $in: group_id_in }
  }
  let info = {}
  if (_.has(req.body, 'freeze')) {
    info['freeze'] = freeze
  }
  if (_.has(req.body, 'lock')) {
    info['lock'] = lock
  }
  let listProxy = await getListProxy(req)
  return next({ update, info, ...listProxy })
}

const getListProxy = async (req) => {
  let query = null
  let options = { page_size }
  let create_time = filterRangePicker('create_time', req.query)
  if (create_time) {
    let { begin, end } = create_time
    query = { ...query, createAt: { $gte: begin, $lt: end } }
    options = { ...options, create_time: req.query['create_time'] }
  }
  if (_.has(req.query, 'group') && !_.isEmpty(req.query['group']) && !/[^\d\|]/.test(req.query['group'])) {
    let group_id_in = req.query['group'].replace(/[^\d\|]/g, '').split('|')
    let group_objectid = await groupProxy.getObjectId({ id: { $in: group_id_in } })
    query = { ...query, group: { $in: group_objectid } }
    let group = []
    for (let e of group_id_in) {
      group.push(parseInt(e))
    }
    options = { ...options, group }
  }
  let query_username = filterFindString('username', req.query, 'username', true)
  if (query_username) {
    let { query_arr, query_str } = query_username
    query = { ...query, $or : query_arr }
    options = { ...options, username: query_str }
  }
  let query_email = filterFindString('email', req.query, 'email', true)
  if (query_email) {
    let { query_arr, query_str } = query_email
    query = { ...query, $or : query_arr }
    options = { ...options, email: query_str }
  }
  if (_.has(req.query, 'lock')) {
    query = { ...query, lock : req.query['lock'].replace(/\s/g, '') === 'true' }
    options = { ...options, lock: req.query['lock'].replace(/\s/g, '') === 'true' }
  }
  if (_.has(req.query, 'freeze')) {
    query = { ...query, freeze : req.query['freeze'].replace(/\s/g, '') === 'true' }
    options = { ...options, freeze: req.query['freeze'].replace(/\s/g, '') === 'true' }
  }
  let { pageCode, limit, skip } = toPageInfo(req.query['page'], page_size)
  options = { ...options, page: pageCode }
  return { query, options, limit, skip }
}